package server;

import io.vertx.core.Handler;
import io.vertx.core.buffer.Buffer;
import io.vertx.core.http.HttpServerRequest;
import io.vertx.core.http.HttpServerResponse;
import model.RpcRequest;
import model.RpcResponse;
import registry.LocalRegistry;
import serializer.JdkSerializer;
import serializer.Serializer;

import java.io.IOException;
import java.lang.reflect.Method;

/**
 * @Author: mengyu
 * @Date: 2024/7/14
 * Http 请求处理
 */
public class HttpServerHandler implements Handler<HttpServerRequest> {
    @Override
    public void handle(HttpServerRequest request) {
        // 指定序列化器
        Serializer serializer = new JdkSerializer();
        // 记录日志
        System.out.println("Received request: "+request.method()+ " "+ request.uri());
        // 异步处理请求
        request.bodyHandler(body ->{
           // 反序列化
            byte[] bytes = body.getBytes();
            RpcRequest rpcRequest = null;
            try {
                rpcRequest = serializer.deserialize(bytes, RpcRequest.class);
            } catch (IOException e) {
                e.printStackTrace();
            }
            // 构建RpcResponse
            RpcResponse rpcResponse = new RpcResponse();
            if(rpcRequest == null){
                rpcResponse.setMessage("rpcRequest is null");
                doResponse(request,rpcResponse,serializer);
            }
            // 服务发现
            try{
                String serviceName = rpcRequest.getServiceName();
                String methodName = rpcRequest.getMethodName();
                Class<?>[] parameterTypes = rpcRequest.getParameterTypes();
                Object[] args = rpcRequest.getArgs();
                // 获取类和方法
                Class<?> impClass = LocalRegistry.get(serviceName);
                Method method = impClass.getMethod(methodName, parameterTypes);
                // 反射执行方法
                Object result = method.invoke(impClass.newInstance(), args);
                // 封装结果
                rpcResponse.setDate(result);
                rpcResponse.setDateType(method.getReturnType());
                rpcResponse.setMessage("ok");
            }catch (Exception e){
                e.printStackTrace();
                rpcResponse.setMessage(e.getMessage());
                rpcResponse.setException(e);
            }
            // 返回
            doResponse(request,rpcResponse,serializer);
        });
    }

    void doResponse(HttpServerRequest request, RpcResponse rpcResponse, Serializer serializer){
        // 设置返回头
        HttpServerResponse httpServerResponse = request.response()
                .putHeader("content-type","application/json");
        // 序列化
        try {
            byte[] serialize = serializer.serialize(rpcResponse);
            httpServerResponse.end(Buffer.buffer(serialize));
        } catch (IOException e) {
            e.printStackTrace();
            httpServerResponse.end(Buffer.buffer());
        }
    }
}
